package example.spring_aop.aspect;

import lombok.extern.slf4j.Slf4j;
import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.annotation.*;
import org.springframework.core.annotation.Order;
import org.springframework.stereotype.Component;

/**
 * @ClassName AspectDemo
 * @Description 切面类 测试 Before Around After 方法的执行顺序
 * @Author ZJX
 * @Date 2024/9/2 16:32
 * @Version 1.0
 */
@Order(1) // 通过@Order 注解 可以改变优先级  数字越大 优先级越低
// 环形的执行顺序    后执行的@Before通知，其对应的@After通知会先执行
//@Aspect
@Component
@Slf4j
public class AspectDemo {

//    一个切面类里面可以有多个切面

    @Pointcut("execution(* example.spring_aop.controller.*.*(..))") // 定义切点表达式
    public void pt(){}; // 切点跨类使用时 需要把切点声明为 public

    @Before("pt()")  // 直接引入切点表达式
    public void doBefore(){
        log.info("Do Before...");
    }


    @Around("execution(* example.spring_aop.controller.*.*(..))")
    public Object doAround(ProceedingJoinPoint joinPoint) throws Throwable {
        log.info("Do BeforeAround...");
        Object proceed = joinPoint.proceed();
        log.info("Do AfterAround...");
        return proceed;
    }

    @After("execution(* example.spring_aop.controller.*.*(..))")
    public void doAfter(){
        log.info("Do After...");
    }

    @AfterReturning("execution(* example.spring_aop.controller.*.*(..))")
    public void doAfterReturning(){
        log.info("Do AfterReturning...");
    }

    @AfterThrowing("execution(* example.spring_aop.controller.*.*(..))")
    public void doAfterThrowing(){
        log.info("Do AfterThrowing...");
    }
}
